﻿package com.onpositive.notes.services;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;

import com.onpositive.data.units.UnitKind;
import com.onpositive.notes.argumnets.DimensionArgumnetModel;
import com.onpositive.notes.argumnets.DimensionValidator;
import com.onpositive.notes.argumnets.EmptyStringFilter;
import com.onpositive.notes.argumnets.StringArgumnetModel;
import com.onpositive.notes.model.IArgumentModel;
import com.onpositive.notes.model.IArgumentValidator;
import com.onpositive.notes.model.ITemplateModel;
import com.onpositive.notes.templates.BasicTemplateModel;

public class TemplateModelsList {
	
	private static final String MODEL_ID_ESTIMATED_CASH = "model-estimated-cash";
	private static final String MODEL_ID_WANT_PRESENT = "model-want-present";
	private static final String MODEL_ID_GET_PERF = "model-get-perf";
	private static final String MODEL_ID_GET_INF = "model-get-inf";
	private static final String MODEL_ID_SELL_PERF = "model-sell-perf";
	private static final String MODEL_ID_SELL_INF = "model-sell-inf";
	private static final String MODEL_ID_BUY_PERF = "model-buy-perf";
	private static final String MODEL_ID_BUY_INF = "model-buy-inf";
	private static final String MODEL_ID_RETURN_MONEY_PERF = "model-return-money-perf";
	private static final String MODEL_ID_RETURN_MONEY_INF = "model-return-money-inf";
	private static final String MODEL_ID_BORROW_PERF = "model-borrow-perf";
	private static final String MODEL_ID_BORROW_INF = "model-borrow-inf";
		
	private static ArrayList<ITemplateModel<?>> modelsList = null ;

	public static ArrayList<ITemplateModel<?>> getModelsList() {
		init() ;
		return modelsList;
	}


	private static void init() {
		
		if( modelsList != null )
			return ;
		
		modelsList = new ArrayList<ITemplateModel<?>>() ;
		
		Locale Locale_RU = new Locale("ru") ;		
		
		HashMap<Locale,ArrayList<String>> bodyMap = new HashMap<Locale,ArrayList<String>>() ;
		HashMap<Locale,String> keyMap ;
		ArrayList<IArgumentModel<?,?>> argModels ;
		ITemplateModel<?> model ;
		ArrayList<ITemplateExecutor> executors ;
		ArrayList<IArgumentValidator> validators ;
		
		
//========== BORROW ============		
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "borrow") ;
		keyMap.put(Locale_RU, "занять") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("sum",true) })) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
			new TemplateExecutorRegistry.BorrowInfExecutor(),
			new TemplateExecutorRegistry.MoneyCounterIncrementorTodo(),
		}) ) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_BORROW_INF, keyMap, bodyMap, argModels, executors, -1, validators ) ;		
		modelsList.add( model ) ;
		
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "borrowed") ;
		keyMap.put(Locale_RU, "занял") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("sum",true) })) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.BorrowPerfExecutor(),
				new TemplateExecutorRegistry.GiveBackInfExecutor(),
				new TemplateExecutorRegistry.MoneyCounterIncrementor(),
			}) ) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_BORROW_PERF, keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
		
//========== RETURN ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "return") ;
		keyMap.put(Locale_RU, "отдать") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("sum",true) })) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GiveBackInfExecutor(),
				new TemplateExecutorRegistry.MoneyCounterDecrementorTodo(),
			}) ) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_RETURN_MONEY_INF,	keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
		
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "returned") ;
		keyMap.put(Locale_RU, "отдал") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("sum",true) })) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GiveBackPerfExecutor(),
				new TemplateExecutorRegistry.BorrowInfExecutor(),
				new TemplateExecutorRegistry.MoneyCounterDecrementor(),
			}) ) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_RETURN_MONEY_PERF, keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
		
//========== BUY ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "buy") ;
		keyMap.put(Locale_RU, "купить") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageContributorTodo()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_BUY_INF,	keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
				
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "bought") ;
		keyMap.put(Locale_RU, "купил") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageContributor()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_BUY_PERF, keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
		
//========== SELL ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "sell") ;
		keyMap.put(Locale_RU, "продать") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageRemoverTodo()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_SELL_INF,	keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
				
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "sold") ;
		keyMap.put(Locale_RU, "продал") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageRemover()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_SELL_PERF, keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;		
	
//========== GET ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "get") ;
		keyMap.put(Locale_RU, "получить") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageContributor()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_GET_INF,	keyMap,	bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
						
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "got") ;
		keyMap.put(Locale_RU, "получил") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageContributor()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_GET_PERF, keyMap, bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
			
//========== WANT ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "want") ;
		keyMap.put(Locale_RU, "хочу") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new StringArgumnetModel("person",true),
						new DimensionArgumnetModel("size",false),
						new DimensionArgumnetModel("weight",false),
						new DimensionArgumnetModel("volume",false),
						new DimensionArgumnetModel("price",false),
						})) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new EmptyStringFilter(),
				new DimensionValidator( UnitKind.SIZE ),
				new DimensionValidator( UnitKind.WEIGHT ),
				new DimensionValidator( UnitKind.VOLUME ),
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.GeneralStorageContributorTodo()
			}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_WANT_PRESENT, keyMap, bodyMap, argModels, executors, -1, validators ) ;
		modelsList.add( model ) ;
		
//========== ESTIMATE CASH ============
		keyMap = new HashMap<Locale, String>() ;
		keyMap.put(Locale.US, "estimated cash") ;
		keyMap.put(Locale_RU, "оценил наличность") ;
		argModels = new ArrayList<IArgumentModel<?,?>>(
				Arrays.asList( new IArgumentModel<?,?>[]{
						new DimensionArgumnetModel("ammount",true) })) ;
		
		executors = new ArrayList<ITemplateExecutor>( Arrays.asList( new ITemplateExecutor[]{
				new TemplateExecutorRegistry.MoneyCounterSetter()
			}) ) ;
		
		validators = new ArrayList<IArgumentValidator>( Arrays.asList( new IArgumentValidator[]{
				new DimensionValidator( UnitKind.CURRENCY )
		}) ) ;
		
		model = new BasicTemplateModel( MODEL_ID_ESTIMATED_CASH, keyMap, bodyMap, argModels, executors, 1, validators ) ;
		modelsList.add( model ) ;		
	}

}
